package com.powernode.dataaccessobject.dao;

import com.powernode.commons.util.DbUtils;

import javax.lang.model.type.DeclaredType;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author Arrebol
 * @Date 2024/8/3 15:26
 * @Project jdbc
 * @Description： 最基础的Dao，所有的Dao应该继承于这个Dao
 */
public class BaseDao {

    /**
     * 这是一个通用的执行insert、delete、update的方法
     *
     * @param updateSql 要执行的增删改SQL语句
     * @param params    需要给SQL语句占位符 ? 赋值的参数
     * @return 数据改变的条数
     * @throws SQLException
     */
    public int executeUpdate(String updateSql, Object... params) throws SQLException {
        Connection conn = DbUtils.getConnection();
        PreparedStatement ps = conn.prepareStatement(updateSql);
        if (params != null && params.length != 0) {
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i + 1, params[i]);
            }
        }
        int count = ps.executeUpdate();
        DbUtils.close(null, ps, conn);
        return count;
    }

    /**
     * 这是一个通用的查询语句
     *
     * @param selectSql 要执行的查询SQL语句
     * @param clazz
     * @param params    需要给SQL语句占位符 ? 赋值的参数
     * @param <T>       泛型
     * @return 查询到的数据集合
     */
    public <T> List<T> executeQuery(String selectSql, Class<T> clazz, Object... params) throws SQLException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        List<T> list = new ArrayList<>();
        Connection conn = DbUtils.getConnection();
        PreparedStatement ps = conn.prepareStatement(selectSql);
        if (params != null && params.length != 0) {
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i + 1, params[i]);
            }
        }
        ResultSet rs = ps.executeQuery();
        //获取查询结果元数据
        ResultSetMetaData metaData = rs.getMetaData();
        //获取列数
        int columnCount = metaData.getColumnCount();
        while (rs.next()) {
            //封装bean对象，将对象添加到list集合
            T obj = clazz.newInstance();
            for (int i = 1; i <= columnCount; i++) {
                //查询结果集中列的名字
                String fieldName = metaData.getColumnLabel(i);
                //列的名字是通过as关键字起别名，就是bean的属性名
                //获取Field对象
                Field declaredFieldfield = clazz.getDeclaredField(fieldName);
                //打破封装
                declaredFieldfield.setAccessible(true);
                //给属性赋值
                declaredFieldfield.set(obj,rs.getObject(i));
            }
            list.add(obj);
        }
        DbUtils.close(rs, ps, conn);
        return list;
    }

    public<T> T queryOne(String selectSql,Class<T> clazz,Object...params) throws SQLException, NoSuchFieldException, InstantiationException, IllegalAccessException {
        List<T> list = executeQuery(selectSql, clazz, params);
        if(list==null || list.size()==0){
            return null;
        }
        return list.get(0);
    }
}
